#ifndef CL_NEWS_POOL_H_INCLUDED
#define CL_NEWS_POOL_H_INCLUDED

#include<string>
#include<vector>
#include "CL_News.h"
#include<set>
#include<map>
#include<string>
#include<Poco/Net/HTTPClientSession.h>
#include<Poco/Net/HTTPRequest.h>
#include<Poco/Net/HTTPResponse.h>
#include<Poco/Net/NetException.h>
#include<Poco/URI.h>
#include<Poco/DateTimeParser.h>
#include<Poco/Timestamp.h>
#include<Poco/Hash.h>
#include<Poco/Path.h>
#include<Poco/File.h>
#include<Poco/InflatingStream.h>
#include<string>
#include <ios>
#include <iostream>
#include <ctime>
#include <ostream>
#include <istream>
#include <sstream>
#include<unistd.h>
#include "unicode/platform.h"
#include "unicode/std_string.h"
#include "unicode/utypes.h"   /* Basic ICU data types */
//#include "unicode/ucnv.h"     /* C   Converter API    */
#include "unicode/ustring.h"  /* some more string fcns*/
#include "unicode/uchar.h"    /* char names           */
#include "unicode/uloc.h"
#include "unicode/unistr.h"
#include "pugixml.hpp"
#include <syslog.h>




class CL_News_pool
{
public:
    static CL_News_pool& get_news_pool();
    static CL_News_pool* get_news_pool_pointer();
    bool add_source_url(const std::string& s);
    CL_News old_news_first();
    CL_News random_news();
    int get_news_count();
    static void set_interval(const time_t t);
    static int get_adaption_rate();
    ~CL_News_pool();
private:
    class CL_RSS_Quelle
    {
    public:
        enum internal_error_codes
        {
            INT_ERR_ALL_OKAY,
            INT_ERR_WRONG_COMPRESSION
        };
        CL_RSS_Quelle(const std::string& u);
        CL_RSS_Quelle();
        void set_url(const std::string& s);
        CL_RSS_Quelle& operator=(const CL_RSS_Quelle& q);
        ~CL_RSS_Quelle();
        int add_news(newsmap&);
        operator bool() const;
        friend newsmap& operator+(newsmap&, CL_RSS_Quelle&);
        struct QError
        {
            std::string ErrorDescription;
            QError();
            QError(const std::string&);
            void set_error(const std::string& s)
            {
                ErrorDescription=s;
            };
        };
    private:
        struct iNetReturn
        {
            std::size_t hashvalue;
            Poco::Net::HTTPResponse::HTTPStatus status;
            internal_error_codes internal_error;
            iNetReturn():hashvalue(0),status(Poco::Net::HTTPResponse::HTTP_OK), internal_error(INT_ERR_ALL_OKAY) {};
        };
        time_t last_connection;
        std::size_t last_feed_hash;
        std::set<std::size_t> last_news_hash;
        std::string url;
        bool is_erroneous;
        QError last_error;
        static Poco::Hash<std::string> myhash;
        std::string write_request_response_2_file(Poco::Net::HTTPRequest&,Poco::Net::HTTPResponse&);
        iNetReturn get_response_utf8(std::string& body);
        int create_news_from_xml(std::string&, newsmap&);
        int parse_rss_20(newsmap& map, pugi::xml_document& rss_doc, pugi::xml_node& version);
        int parse_atom(newsmap& map, pugi::xml_document& rss_doc, pugi::xml_node& version);
        void handle_atom_item(CL_newsitem&,pugi::xml_node&);
        std::string search_atom_item_for_description(pugi::xml_node&);
        std::string search_atom_item_for_title(pugi::xml_node&);
        std::string search_atom_item_for_author(pugi::xml_node&);
        std::string search_atom_item_for_link(pugi::xml_node&);
        time_t search_atom_item_for_pubDate(pugi::xml_node&);
        time_t timestrings_to_time_t(const std::string&);
        static const std::string accepted_mime_types;
        void process_status_200(CL_News_pool::CL_RSS_Quelle::iNetReturn& iNR,
                                Poco::Net::HTTPResponse& response,
                                std::string& body, Poco::Net::HTTPClientSession& client,
                                std::istream& responsestream);
        std:: string strip_from_html(const std::string& s);
        std::string last_modified;
    };
    static CL_News_pool* news_pool_singleton;
    static newsmap mynewsmap;
    static std::map<std::string,CL_News_pool::CL_RSS_Quelle> sources;
    static time_t last_update;
    static time_t interval;
    static time_t max_age;
    static key_pair last_key_pair;
    static int adaption_rate;
    static char* prioritystrings[];
    static int message_level;
    static std::string username;
    static std::string userhome;
    static void update();
    static void force_update();
    static void delete_old_news(newsmap&);

    CL_News_pool();
    CL_News_pool& operator=(const CL_News_pool&);


    friend newsmap& operator+=(newsmap& m, CL_News_pool::CL_RSS_Quelle& q);
    friend newsmap& operator+(newsmap& m, CL_News_pool::CL_RSS_Quelle& q);
    static void mylog(std::string context, std::string message, int prio=LOG_ERR);
    static void process_mem_usage(double& vm_usage, double& resident_set);

};


#endif // CL_NEWS_POOL_H_INCLUDED
